﻿using System;
using System.Collections.ObjectModel;
using System.Globalization;

namespace Silverlight
{
    /// <summary>
    /// Provides DataColumnCollection functionality
    /// </summary>
    public class DataColumnCollection : Collection<DataColumn>
    {
        #region Events
        /// <summary>
        /// Is reaised when schema was changed
        /// </summary>
        public event EventHandler<DataSetEventArgs> SchemaChanged;
        #endregion

        #region Constructors
        /// <summary>
        /// Default constructor
        /// </summary>
        internal DataColumnCollection()
        {
        }
        #endregion

        #region Indexers
        /// <summary>
        /// Gets DataColumn with specified name
        /// </summary>
        /// <param name="name">DataColumn name</param>
        /// <returns>DataColumn if found, otherwise null</returns>
        public DataColumn this[string name]
        {
            get
            {
                // Validate argument
                if (string.IsNullOrEmpty(name))
                {
                    throw new ArgumentNullException("name");
                }

                // Do case insensitive search
                string caseInsensitiveName = name.ToUpper(CultureInfo.InvariantCulture);
                foreach (DataColumn dataColumn in this)
                {
                    if (dataColumn.ColumnName.ToUpper(CultureInfo.InvariantCulture).Equals(caseInsensitiveName))
                    {
                        return dataColumn;
                    }
                }

                return null;
            }
        }
        #endregion

        #region Methods
        /// <summary>
        /// Adds DataColumn to DataColumnCollection
        /// </summary>
        /// <param name="dataColumn">DataColumn for adding</param>
        /// <returns>Added DataColumn</returns>
        public new DataColumn Add(DataColumn dataColumn)
        {
            // Validate argument
            if (dataColumn == null)
            {
                throw new ArgumentNullException("dataColumn");
            }

            if (string.IsNullOrEmpty(dataColumn.ColumnName))
            {
                dataColumn.ColumnName = "Column" + (base.Count + 1);
            }

            dataColumn.Index = base.Count;
            dataColumn.SchemaChanged += new EventHandler<DataSetEventArgs>(DataColumn_SchemaChanged);
            base.Add(dataColumn);

            DataSetEventArgs dataSetEventArgs = new DataSetEventArgs();
            dataSetEventArgs.Command = "Add";
            dataSetEventArgs.Column = dataColumn;
            OnSchemaChanged(dataSetEventArgs);
            
            return dataColumn;
        }

        /// <summary>
        /// Raises SchemaChanged event
        /// </summary>
        /// <param name="dataSetEventArgs">Event arguments</param>
        private void OnSchemaChanged(DataSetEventArgs dataSetEventArgs)
        {
            if (SchemaChanged != null)
            {
                SchemaChanged(this, dataSetEventArgs);
            }
        }

        /// <summary>
        /// Removes DataColumn from DataColumnCollection
        /// </summary>
        /// <param name="dataColumn">DataColumn for removing</param>
        public new void Remove(DataColumn dataColumn)
        {
            DataSetEventArgs dataSetEventArgs = new DataSetEventArgs();
            dataSetEventArgs.Command = "Remove";
            dataSetEventArgs.Column = dataColumn;
            OnSchemaChanged(dataSetEventArgs);

            // Remove column from table schema
            base.Remove(dataColumn);
        }
        #endregion

        #region Event Handlers
        /// <summary>
        /// Handles DataColumn.SchemaChanged event
        /// </summary>
        /// <param name="sender">Event source</param>
        /// <param name="e">Event arguments</param>
        private void DataColumn_SchemaChanged(object sender, DataSetEventArgs e)
        {
            this.OnSchemaChanged(e);
        }
        #endregion
    }
}
